﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

namespace ViCode_LeVi.ExtraWindowStyles
{
    public class WindowBehavior
    {
        #region Win32 imports
        private const int GWL_STYLE = -16;
        private const int WS_SYSMENU = 0x80000;
        private const int WS_MINIMIZE = -131073;
        private const int WS_MAXIMIZE = -65537;
        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
        #endregion

        private static readonly Type OwnerType = typeof(WindowBehavior);
        #region CanMinimize (attached property)
        public static readonly DependencyProperty CanMinimizeProperty =
          DependencyProperty.RegisterAttached("CanMinimize", typeof(bool), OwnerType,
          new FrameworkPropertyMetadata(false, new PropertyChangedCallback(CanMinimizeChangedCallback)));

        [AttachedPropertyBrowsableForType(typeof(Window))]
        public static bool GetCanMinimize(Window obj)
        {
            return (bool)obj.GetValue(CanMinimizeProperty);
        }
        [AttachedPropertyBrowsableForType(typeof(Window))]
        public static void SetCanMinimize(Window obj, bool value)
        {
            obj.SetValue(CanMinimizeProperty, value);
        }
        private static void CanMinimizeChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var window = d as Window;
            if (window == null) return;
            var hideMinimizeButton = (bool)e.NewValue;
            if (hideMinimizeButton && !GetIsEnableMinimizeButton(window))
            {
                if (!window.IsLoaded)
                {
                    window.Loaded += LoadedDelegate;
                }
                else
                {
                    CanMinimize(window);
                }
                SetIsEnableMinimizeButton(window, true);
            }
        }
        private static readonly RoutedEventHandler LoadedDelegate = (sender, args) =>
        {
            if (sender is Window == false)
                return;
            var w = (Window)sender;
            CanMinimize(w);
            w.Loaded -= LoadedDelegate;
        };
        private static void CanMinimize(Window w)
        {
            var hwnd = new WindowInteropHelper(w).Handle;
            long value = GetWindowLong(hwnd, GWL_STYLE);
            SetWindowLong(hwnd, GWL_STYLE, (int)(value & WS_MINIMIZE));
        }
        #endregion
        #region IsEnableMinimizeButton (readonly attached property)
        private static readonly DependencyPropertyKey IsEnableMinimizeButtonKey =
          DependencyProperty.RegisterAttachedReadOnly("IsEnableMinimizeButton", typeof(bool), OwnerType,
          new FrameworkPropertyMetadata(false));
        public static readonly DependencyProperty IsEnableMinimizeButtonProperty = IsEnableMinimizeButtonKey.DependencyProperty;
        [AttachedPropertyBrowsableForType(typeof(Window))]
        public static bool GetIsEnableMinimizeButton(Window obj)
        {
            return (bool)obj.GetValue(IsEnableMinimizeButtonProperty);
        }
        private static void SetIsEnableMinimizeButton(Window obj, bool value)
        {
            obj.SetValue(IsEnableMinimizeButtonKey, value);
        }
        #endregion
    }
}
